#define _CRT_SECURE_NO_WARNINGS
/*
完成父线程和子线程的同步。父线程创建子线程后进入阻塞状态，子线程运行完毕后再
唤醒。
相关系统调用：
等待对象 WaitForSingleObject(), WaitForMultipleObjects();
信号量对象 CreateSemaphore(), OpenSemaphore(), ReleaseSemaphore();
HANDLE WINAPI CreateSemaphore(
 _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes
 _In_ LONG lInitialCount,
 _In_ LONG lMaximumCount,
 _In_opt_ LPCTSTR lpName
);
第一个参数：安全属性，如果为 NULL 则是默认安全属性
第二个参数：信号量的初始值，要>=0 且<=第三个参数
第三个参数：信号量的最大值
第四个参数：信号量的名称
返回值：指向信号量的句柄，如果创建的信号量和已有的信号量重名，那么返回已经存
在的信号量句柄。
*/
#include <windows.h>
#include <stdio.h>

// 全局信号量句柄
HANDLE g_hSemaphore;

// 子线程函数
DWORD WINAPI ThreadFunc(LPVOID lpParam) {
    printf("ThreadA\n");
    printf("ThreadB\n");
    printf("ThreadC\n");
    printf("子线程执行\n");

    // 模拟一些工作
    Sleep(2000);

    printf("子线程执行完成\n");

    // 释放信号量，通知父线程
    if (!ReleaseSemaphore(g_hSemaphore, 1, NULL)) {
        printf("释放信号量失败: %d\n", GetLastError());
        return 1;
    }

    printf("唤醒父线程\n");
    return 0;
}

int main() {
    HANDLE hThread;
    DWORD threadId;

    // 创建信号量，初始计数为0
    g_hSemaphore = CreateSemaphore(NULL, 0, 1, TEXT("MySemaphore"));
    if (g_hSemaphore == NULL) {
        printf("创建信号量失败: %d\n", GetLastError());
        return 1;
    }

    printf("Hello, This is a Thread\n");
    printf("hello world\n");

    // 创建子线程
    hThread = CreateThread(
        NULL,                   // 默认安全属性
        0,                      // 使用默认堆栈大小  
        ThreadFunc,             // 线程函数名称
        NULL,                   // 参数传入线程函数
        0,                      // 立即运行线程 
        &threadId);             // 返回线程标识符

    if (hThread == NULL) {
        printf("创建线程失败: %d\n", GetLastError());
        CloseHandle(g_hSemaphore);
        return 1;
    }

    printf("父线程执行\n");
    printf("父线程等待子线程完成\n");

    // 父线程等待信号量
    WaitForSingleObject(g_hSemaphore, INFINITE);

    printf("子线程执行完毕，父线程继续执行\n");

    // 关闭线程句柄和信号量句柄以释放资源
    CloseHandle(hThread);
    CloseHandle(g_hSemaphore);

    return 0;
}

